#include "Res.h"

char currentLoginUserName[128] = {0};

void ViewMerchants(int sID)
{
    MSG msg;
    msg.identity = client;
    msg.type = ViewMerchant;

    // 把消息发送给服务器
    int ret = send(sID, &msg, sizeof(msg), 0);
    if (ret == -1)
    {
        printf("发送数据出错了\n");
        return;
    }

    // 接收查询结果的元数据（行列数）
    ret = recv(sID, &msg, sizeof(MSG), 0);
    QUREY_RST *temp = (QUREY_RST *)msg.buf;

    printf("收到查询结果: row = %d, col = %d\n", temp->row, temp->col);
    int temp_row = temp->row;
    printf("商店名：\n");
    // 接收并打印每一行数据
    for (int i = 0; i < temp_row; i++) // 从0开始接收所有行
    {
        ret = recv(sID, &msg, sizeof(MSG), 0);
        if (ret <= 0) // 如果没有数据，或者连接关闭，则退出
        {
            printf("接收数据出错或连接关闭\n");
            break;
        }
        printf("%s\n", msg.buf);
    }
    printf("数据接收完成\n");
}

void SelectMerchants(int sID)
{
    MSG msg;
    MENU selectMenu;
    msg.identity = client;
    msg.type = SelectMerchant;
    while (getchar() != '\n')
        ;
    printf("请输入你想点餐的商家名：");
    fgets(selectMenu.shoreID, sizeof(selectMenu.shoreID), stdin);
    selectMenu.shoreID[strcspn(selectMenu.shoreID, "\n")] = 0; // 去除尾部换行符
    memcpy(msg.buf, &selectMenu, sizeof(selectMenu));

    // 把消息发送给服务器
    int ret = send(sID, &msg, sizeof(msg), 0);
    if (ret == -1)
    {
        printf("发送数据出错了\n");
        return;
    }
    // 接收查询结果的元数据（行列数）
    ret = recv(sID, &msg, sizeof(MSG), 0);
    QUREY_RST *temp = (QUREY_RST *)msg.buf;

    printf("收到查询结果: row = %d, col = %d\n", temp->row, temp->col);
    int temp_row = temp->row;
    printf("商品名  价格  销量\n");
    // 接收并打印每一行数据
    for (int i = 0; i < temp_row; i++) // 从0开始接收所有行
    {
        ret = recv(sID, &msg, sizeof(MSG), 0);
        if (ret <= 0) // 如果没有数据，或者连接关闭，则退出
        {
            printf("接收数据出错或连接关闭\n");
            break;
        }
        COMMODITY *show = (COMMODITY *)msg.buf;
        printf("  %s   %.2f   %d\n", show->dishName, show->price, show->sales);
    }
    printf("数据接收完成\n");
}

void OrderMeal(int sID)
{
    MSG msg;
    MENU selectMenu;
    msg.identity = client;
    msg.type = OrderMeals;
    while (getchar() != '\n');
    printf("请输入你想点餐的商家名：");
    fgets(selectMenu.shoreID, sizeof(selectMenu.shoreID), stdin);
    selectMenu.shoreID[strcspn(selectMenu.shoreID, "\n")] = 0; // 去除尾部换行符

    while (getchar() != '\n');
    printf("请输入你想要的餐品名：");
    fgets(selectMenu.dishName, sizeof(selectMenu.dishName), stdin);
    selectMenu.dishName[strcspn(selectMenu.dishName, "\n")] = 0; // 去除尾部换行符
    while (getchar() != '\n');

    printf("请输入你想要的份数：");
    scanf("%d", &selectMenu.Sales);

    strcpy(selectMenu.ClientName, currentLoginUserName);

    memcpy(msg.buf, &selectMenu, sizeof(selectMenu));

    // 把消息发送给服务器
    int ret = send(sID, &msg, sizeof(msg), 0);
    if (ret == -1)
    {
        printf("发送数据出错了\n");
        return;
    }

    ret = recv(sID, &msg, sizeof(MSG), 0);
    if (msg.type == ok)
    {
        printf("点单成功\n");
        double price = atof(msg.buf);
        printf("请支付%.2f元\n", price);
        return;
    }
    if (-1 == ret)
    {
        printf("接收数据出错了\n");
        return;
    }
}

void ViewOrderStatus(int sID)
{
    MSG msg;
    MENU selectMenu;
    msg.identity = client;
    msg.type = ViewOrderStates;
    strcpy(msg.buf, currentLoginUserName);

    int ret = send(sID, &msg, sizeof(msg), 0);
    if (ret == -1)
    {
        printf("发送数据出错了\n");
        return;
    }

    // 接收查询结果的元数据（行列数）
    ret = recv(sID, &msg, sizeof(MSG), 0);
    QUREY_RST *temp = (QUREY_RST *)msg.buf;

    printf("收到查询结果: row = %d, col = %d\n", temp->row, temp->col);
    int temp_row = temp->row;
    printf("订单号 商家名 餐品名 点餐数据量 价格 订单状态 时间:\n");
    for (int i = 0; i < temp_row; i++) // 从0开始接收所有行
    {
        ret = recv(sID, &msg, sizeof(MSG), 0);
        if (ret <= 0) // 如果没有数据，或者连接关闭，则退出
        {
            printf("接收数据出错或连接关闭\n");
            break;
        }
        MENU *show = (MENU *)msg.buf;

        printf("%d  %s  %s  %d  %.2f  %s  %s\n", show->orderID, show->shoreID, show->dishName, show->Sales, show->Price, show->OrderState, show->Time);
    }
}

// 工作线程，接受服务器返回来的消息
void *work(void *pArg)
{
    // 把套接字从地址里面取出来
    int sID = *(int *)pArg;
    printf("接受数据的线程开始工作了\n");
    // 用户连接后会创建当前线程，并且会把用户的套接字id通过参数传入进来
    // 这里是把套接字从地址里面取出来
    MSG msg;
    struct sockaddr_in clientAddr;
    socklen_t len = sizeof(clientAddr);
    int ret = 0;
    // 接收消息
    while (0 < (ret = recv(sID, &msg, sizeof(MSG), 0)))
    {
        SINGLE_CHAT *pSC = (SINGLE_CHAT *)msg.buf;
        printf("接受到%s发来的消息:%s\n", pSC->selfName, pSC->text);
    }
    if (ret <= 0)
    {
        printf("接受数据出错了，服务器可能被关掉了\n");
    }
}

void ClientPrivateChat(int sID)
{
    MSG msg;
    msg.identity = client;
    msg.type = UserOpensChat;

    strcpy(msg.buf, currentLoginUserName);
    int send_ret = send(sID, &msg, sizeof(msg), 0);
    if (send_ret == -1)
    {
        printf("发送数据出错了\n");
    }

    //  if(-1==recv(sID, &msg, sizeof(MSG), 0))
    //  {
    //     printf("接收数据错误\n");
    //  }
    //  printf("%s\n",msg.buf);

    SINGLE_CHAT sc;
    strcpy(sc.selfName, currentLoginUserName); // 自己的名字

    msg.type = FindSelfChats;
    memcpy(msg.buf, &sc, sizeof(sc));
    send_ret = send(sID, &msg, sizeof(msg), 0);
    if (send_ret == -1)
    {
        printf("发送数据出错了\n");
    }

    int ret = recv(sID, &msg, sizeof(MSG), 0);
    QUREY_RST *pQR = (QUREY_RST *)msg.buf;

    if (pQR->row > 0)
    {
        for (int i = 0; i < pQR->row; i++)
        {
            if (-1 == recv(sID, &msg, sizeof(MSG), 0))
            {
                perror("接受数据错误\n");
            }
            SINGLE_CHAT *rec = (SINGLE_CHAT *)msg.buf;

            printf("%s,来自%s发来的消息:%s\n", rec->time, rec->destName, rec->text);
        }
    }
    else
    {
        printf("没有用户发来消息\n");
    }
    printf("请输入对方的用户名:");
    scanf("%s", sc.destName);

    pthread_t pt;
    // 启动一个接受消息的线程
    pthread_create(&pt, NULL, work, &sID);

    while (1)
    {
        msg.type = WithMerchantPrivateChat;
        printf("请输入聊天的内容\n");
        scanf("%s", sc.text);

        memcpy(msg.buf, &sc, sizeof(sc));

        // 把消息发送给服务器
        int ret = send(sID, &msg, sizeof(msg), 0);
        if (ret == -1)
        {
            printf("发送数据出错了\n");
            break;
        }

        if (strcmp(sc.text, "quit") == 0)
        {
            msg.type = UserCloseChat;
            strcpy(msg.buf, currentLoginUserName);
            send_ret = send(sID, &msg, sizeof(msg), 0);
            if (send_ret == -1)
            {
                printf("发送数据出错了\n");
            }

            pthread_cancel(pt);
            break;
        }
    }
}

void client_page(int sID)
{
    int select_function;
    while (1)
    {
        printf("1. 查看所有商家 2.查看商家商品 3.点单\n");
        printf(" 4.查看订单状态 5.与商家私聊 6.退出\n");
        scanf("%d", &select_function);
        switch (select_function)
        {
        case 1:
            system("clear");
            ViewMerchants(sID);
            break;
        case 2:
            system("clear");
            SelectMerchants(sID);
            break;
        case 3:
            system("clear");
            OrderMeal(sID);
            break;
        case 4:
            system("clear");
            ViewOrderStatus(sID);
            break;
        case 5:
            system("clear");
            ClientPrivateChat(sID);
            break;
        case 6:
            system("clear");
            return;
        default:
            printf("输入错误，请重新输入\n");
            break;
        }
    }
}

int userLogin(int sID)
{
    RGU rgu; // 登录可以重用注册的结构体
    while (getchar() != '\n');
    printf("请输入用户名和密码:\n");
    scanf("%s%s", rgu.name, rgu.pwd);

    MSG msg;
    msg.identity = client;
    msg.type = Login;
    memcpy(msg.buf, &rgu, sizeof(rgu)); // 把注册结构体拷贝到消息结构体的仓库中

    // 把消息发送给服务器
    int ret = send(sID, &msg, sizeof(msg), 0);
    if (ret == -1)
    {
        printf("发送数据出错了\n");
        return -1;
    }

    // 接受服务器的回复
    struct sockaddr_in serverAddr;
    socklen_t len = sizeof(serverAddr);
    // clientAddr是对方的地址,len地址的长度
    ret = recv(sID, &msg, sizeof(msg), 0);
    if (msg.type == ok)
    {
        printf("用户登陆成功\n");
        sleep(1);
        strcpy(currentLoginUserName, rgu.name); // 把用户名保存到全局变量中，其他地方都可以使用
        system("clear");
        client_page(sID);
        // printf("1.聊天 2.加好友 3.发朋友圈 4.返回上级菜单")
        return 1;
    }
    else
    {
        printf("还没有注册或者用户名密码错误\n");
        return -1;
    }
}

int registerUser(int sID)
{
    RGU rgu;
    while (getchar() != '\n');
    
    printf("请输入用户名:");
    fgets(rgu.name, sizeof(rgu.name), stdin);
    rgu.name[strcspn(rgu.name, "\n")] = 0; // 去除尾部换行符

    printf("请输入密码:");
    fgets(rgu.pwd, sizeof(rgu.pwd), stdin);
    rgu.pwd[strcspn(rgu.pwd, "\n")] = 0;

    printf("请输入你的电话号码:");
    fgets(rgu.phone, sizeof(rgu.phone), stdin);
    rgu.phone[strcspn(rgu.phone, "\n")] = 0;

    printf("请输入你的外卖配送地址:");
    fgets(rgu.address, sizeof(rgu.address), stdin);
    rgu.address[strcspn(rgu.address, "\n")] = 0;

    MSG msg;
    msg.identity = client;
    msg.type = Register;
    memcpy(msg.buf, &rgu, sizeof(rgu)); // 把注册结构体拷贝到消息结构体的仓库中

    // 把消息发送给服务器
    int ret = send(sID, &msg, sizeof(msg), 0);
    if (ret == -1)
    {
        printf("发送数据出错了\n");
        return -1;
    }
}

int main(int count, char *arg[])
{
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;   // IPV4的网络地址版本
    sin.sin_port = htons(9000); // 把9000号端口转为网络字节序并赋值给端口参数

    u_int32_t ip = 0;
    // 把字符串ip地址转为网络字节序ip
    inet_pton(AF_INET, "192.168.249.129", &ip);
    sin.sin_addr.s_addr = ip;

    // 创建一个tcp套接字，参数1指定地址族，参数2指定协议，SOCK_STREAM代表是TCP，SOCK_DGRAM代表UDP
    int sID = socket(AF_INET, SOCK_STREAM, 0);

    while (1)
    {
        int is_connect = connect(sID, (struct sockaddr *)&sin, sizeof(struct sockaddr_in));
        if (is_connect == 0)
        {
            MSG msg;
            msg.identity = client;
            msg.type = -1;
            int ret = send(sID, &msg, sizeof(MSG), 0);
            if (-1 == ret)
            {
                perror("发送失败\n");
                continue;
            }
            break;
        }
        else
        {
            perror("连接服务器中...");
            sleep(1);
        }
    }

    char buf[128];
    while (1)
    {
        printf("请选择你要的操作：1.登录 2.注册 3.退出\n");
        scanf("%s", buf);
        if (strcmp(buf, "1") == 0)
        {
            system("clear");
            userLogin(sID);
        }
        else if (strcmp(buf, "2") == 0) // 注册
        {
            system("clear");
            if (-1 == registerUser(sID))
            {
                printf("注册失败了\n");
            }
            system("clear");
        }
        else if (strcmp(buf, "3") == 0) // 注册
        {
            return 0;
        }
    }

    close(sID);

    return 0;
}